import { AxiosRequestConfig, AxiosResponse, AxiosError, Method } from 'axios'
import { useGlobalStore } from '@/stores/global'
import { useUserStore } from '@/stores/user'
import { PageData, PageProps, ComponentData } from '@/stores/editor'

// export interface WorkProps {
//   id?: number // 自增 id
//   uuid: string // 短链接 uuid，h5 url 中使用，隐藏真正的 id
//   title: string // 标题
//   desc: string // 副标题，描述
//   coverImg?: string // 缩略图
//   content?: { [key: string]: any } // 内容数据 // content: { components: [{},{},{}], props: { backgroundColor: 'white }}
//   isTemplate?: boolean // true 模版 false 非模版
//   isPublic?: boolean // 是否公开到首页，默认 false，模版用
//   isHot?: boolean // 是否 hot, 默认 false，模版用
//   author: string // 作者 username
//   copiedCount: number // 被复制的次数
//   status?: 0 | 1 | 2 | 3 // 状态：0-删除 1-未发布 2-发布 3-管理员强制下线
//   user: Types.ObjectId // 作者的 ID，链接到用户表
//   latestPublishAt?: Date
//   channels?: ChannelProps[]
// }

export interface RespData<T = any> {
  errno: number
  data: T
  message?: string
}

export interface ListData<T> {
  list: T[]
  count: number
}

export interface UploadData {
  url: string
}

// 后端返回的作品字段
export interface WorkData extends Omit<PageData, 'props' | 'setting'> {
  content: {
    components: ComponentData[] // 一定会有这个字段
    props?: PageProps
    setting?: { [key: string]: any }
  }
}

export type TemplateData = Required<Omit<PageData, 'props' | 'setting'>>

export type ICustomAxiosConfig = AxiosRequestConfig & { opName?: string }
export const baseBackendURL = import.meta.env.VITE_BASE_EDITOR_API
export const baseH5URL = import.meta.env.VITE_BASE_H5_URL

const instance = axios.create({
  baseURL: `${baseBackendURL}/api`,
  timeout: 2000 * 1000
})

instance.interceptors.request.use(config => {
  const global = useGlobalStore()
  const newConfig = config as ICustomAxiosConfig
  global.setError({ status: false, message: '' })
  // config.headers.common['Authorization'] = `Bearer ${user.token}`
  global.startLoading({ opName: newConfig.opName })
  return config
})
instance.interceptors.response.use(
  (response: AxiosResponse<RespData>) => {
    const global = useGlobalStore()
    const newConfig = response.config as ICustomAxiosConfig
    global.finishLoading({ opName: newConfig.opName })
    const { errno, message } = response.data
    if (errno !== 0) {
      let errorMessage = message
      if (errno === 101004) {
        errorMessage = '登录状态已过期 请重新登录'
        const user = useUserStore()
        user.logout()
      }
      global.setError({ status: true, message: errorMessage })
      return Promise.reject(response.data)
    }
    return response
  },
  (error: AxiosError) => {
    const global = useGlobalStore()
    const newConfig = error.config as ICustomAxiosConfig
    global.setError({ status: true, message: '服务器异常，请稍后再试' })
    global.finishLoading({ opName: newConfig.opName })
    return Promise.reject(error)
  }
)
export async function request<T = any>(url: string, method: Method, opName?: string): Promise<RespData<T>>
export async function request<T = any>(url: string, method: Method, data?: any, opName?: string): Promise<RespData<T>>
export async function request<T = any>(url: string, method: Method, data?: any, opName?: string) {
  if (data && typeof data === 'string') {
    opName = data
    data = {}
  }
  const newConfig: ICustomAxiosConfig = { method, opName }
  if (method === 'get' || method === 'GET') {
    newConfig.params = data
  } else {
    newConfig.data = data
  }
  const res = await instance<RespData<T>>(url, newConfig)
  return res.data
}

// 上传单个文件 支持 file blob
export async function uploadFile<T = { url: string }>(url: string, file: Blob, fileName = 'screenshot.png') {
  const newFile = file instanceof File ? file : new File([file], fileName)
  const formData = new FormData()
  formData.append(newFile.name, newFile)
  const res = await instance.post<RespData<T>>(url, formData, {
    headers: {
      'Content-Type': 'multipart/form-data'
    }
  })
  return res.data
}

// 上传多个文件
export async function uploadMultipartFiles<T = any>(url: string, data: { [key: string]: any }) {
  const keys = Object.keys(data)
  const formData = new FormData()
  keys.forEach(key => {
    formData.append(key, data[key])
  })
  const res = await instance.post<RespData<T>>(url, formData, {
    headers: {
      'Content-Type': 'multipart/form-data'
    }
  })
  return res.data
}

export default instance
